/**
 * @author zqd	差旅小组
 * 上午11:07:43
 */
package com.cbts.dao.impl;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.cbts.dao.BaseDao;
import com.cbts.util.Page;

public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T>{
	private Class entityClass;	//T对应类型

	public BaseDaoImpl(){	//反射方式获得对应泛型实体类
		Type genType=getClass().getGenericSuperclass();
		Type[] params=((ParameterizedType)genType).getActualTypeArguments();
		entityClass=(Class)params[0];
	}

	/* 
	 * @see com.xianer.dao.BaseDao#delete(java.lang.Object)
	 */
	public boolean delete(T t) {
		// zqd 下午03:15:37
		try{
			this.getHibernateTemplate().delete(t);
			return true;
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
	}

	/* 
	 * @see com.xianer.dao.BaseDao#findAll()
	 */
	@SuppressWarnings("unchecked")
	public Page<T> findAll() {
		// zqd 下午03:15:37
		final Page p=new Page<T>();
		final List<T> list=this.getHibernateTemplate().loadAll(entityClass);
		p.setPageItems(list);
		p.setTotalPageNum(list.size());
		return p;
	}

	/* 
	 * @see com.xianer.dao.BaseDao#findByProperty(java.lang.String, java.lang.Object[], int, int)
	 */
	@SuppressWarnings("unchecked")
	public Page<T> findByProperty(final String wherehql, final Object[] values,
			final int firstResult, final int maxResult) {
		// zqd 下午03:15:37
		final Page p=new Page<T>();
		final String classname=entityClass.getSimpleName();
		return (Page<T>)getHibernateTemplate().execute(new HibernateCallback(){
			 public Object doInHibernate(Session session)
				throws HibernateException, SQLException {
				 Query query = session.createQuery("select o from "+ classname+ " o "+(wherehql==null || "".equals(wherehql.trim())? "": "where 1=1 "+ wherehql));
                                setQueryParams(query, values);
					if(firstResult!=-1 && maxResult!=-1) query.setFirstResult(firstResult).setMaxResults(maxResult);
					p.setPageItems(query.list());
					query = session.createQuery("select count(*) from "+ classname+ " o "+(wherehql==null || "".equals(wherehql.trim())? "": "where 1=1 "+ wherehql));
                                       setQueryParams(query, values);
					//if(query.uniqueResult())
                    p.setTotalPageNum((Long)query.uniqueResult());
					return p;
			 }
		});
	}

	/* 
	 * @see com.xianer.dao.BaseDao#get(java.io.Serializable)
	 */
	@SuppressWarnings("unchecked")
	public T get(Serializable id) {
		// zqd 下午03:15:37
		try{
			T t = (T)this.getHibernateTemplate().get(entityClass, id);
			return t;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
		
		
	}

	/* 
	 * @see com.xianer.dao.BaseDao#getCount(java.lang.String, java.lang.Object[])
	 */
	@SuppressWarnings("unchecked")
	public long getCount(String wherehql,final Object[] values) {
		// zqd 下午03:15:37
		final String hql="select count(*) from "+ 
			this.entityClass.getSimpleName()+" o "+(wherehql==null||"".equals(wherehql.trim())?
			"": "where 1=1 "+ wherehql);
		return (Long)getHibernateTemplate().execute(new HibernateCallback(){
			  public Object doInHibernate(Session session)
				throws HibernateException, SQLException { 
			Query query = session.createQuery(hql);
			setQueryParams(query, values);
			return query.uniqueResult();
		}
		  });
	}

	/* 
	 * @see com.xianer.dao.BaseDao#queryUnique(java.lang.String, java.lang.Object[], int, int)
	 */
	public T queryUnique(String wherehql, Object[] values) {
		// zqd 下午03:15:37
		//if()
		List<T> list=this.findByProperty(wherehql, values, 0, 1).getPageItems();
		if(!list.isEmpty())
			return list.get(0);
		else
			return null;
	}

	/* 
	 * @see com.xianer.dao.BaseDao#save(java.lang.Object)
	 */
	public boolean save(T t) {
		// zqd 下午03:15:37
		try{
			this.getHibernateTemplate().save(t);
			return true;
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
	}

	/* 
	 * @see com.xianer.dao.BaseDao#update(java.lang.Object)
	 */
	public boolean update(T t) {
		// zqd 下午03:15:37
		try{
			this.getHibernateTemplate().update(t);
			return true;
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 设置hql语句参数
	 * @param query
	 * @param values
	 */
	protected static void setQueryParams(Query query, Object[] values){
		if(values!=null && values.length>0){
			for(int i=0; i<values.length; i++){
				query.setParameter(i, values[i]);
			}
		}
	}

	/* 
	 * 插入或更新列表
	 * @see com.cbts.dao.BaseDao#saveList(java.util.List)
	 */
	@SuppressWarnings("unchecked")
	public boolean saveOrUpdate(final List<T> list) {
		
		// zqd 下午02:54:41
				return getHibernateTemplate().execute(new HibernateCallback(){
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						// zqd 下午02:57:20
						try{
							for(int i=0;i<list.size();i++){
								getHibernateTemplate().saveOrUpdate(list.get(i));
								
								if(i%50==0){	//清空session
									session.flush();
									session.clear();
								}
							}
							session.flush();
							session.clear();
							return true;
						}catch(Exception e){
							e.printStackTrace();
							return false;
						}
					}
				});
	}
	/* 
	 * @see com.cbts.dao.BaseDao#saveList(java.util.List)
	 */
	@SuppressWarnings("unchecked")
	public boolean saveList(final List<T> list) {
		// zqd 下午02:54:41
		return getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				// zqd 下午02:57:20
				try{
					for(int i=0;i<list.size();i++){
						getHibernateTemplate().save(list.get(i));
						
						if(i%50==0){	//清空session
							session.flush();
							session.clear();
						}
					}
					session.flush();
					session.clear();
					return true;
				}catch(Exception e){
					e.printStackTrace();
					return false;
				}
			}
		});
	}

	/* 
	 * 删除列表
	 * @see com.cbts.dao.BaseDao#saveList(java.util.List)
	 */
	@SuppressWarnings("unchecked")
	public boolean deleteList(final List<T> list) {
		
		// zqd 下午02:54:41
				return getHibernateTemplate().execute(new HibernateCallback(){
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						// zqd 下午02:57:20
						try{
							for(int i=0;i<list.size();i++){
								
								getHibernateTemplate().delete(list.get(i));
								
								if(i%50==0){	//清空session
									session.flush();
									session.clear();
								}
							}
							session.flush();
							session.clear();
							return true;
						}catch(Exception e){
							e.printStackTrace();
							return false;
						}
					}
				});
	}
	/* 
	 * 更新列表
	 * @see com.cbts.dao.BaseDao#saveList(java.util.List)
	 */
	@SuppressWarnings("unchecked")
	public boolean updateList(final List<T> list) {
		
		// zqd 下午02:54:41
				return getHibernateTemplate().execute(new HibernateCallback(){
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						// zqd 下午02:57:20
						try{
							for(int i=0;i<list.size();i++){
								getHibernateTemplate().update(list.get(i));
								if(i%50==0){	//清空session
									session.flush();
									session.clear();
								}
							}
							session.flush();
							session.clear();
							return true;
						}catch(Exception e){
							e.printStackTrace();
							return false;
						}
					}
				});
	}

	/* 
	 * 按页查找
	 * @see com.cbts.dao.BaseDao#findAllByPage(int, int)
	 */
	@SuppressWarnings("unchecked")
	public Page<T> findAllByPage(final int pageNum, final int maxResult) {
		// zqd 上午11:14:10
		return (Page<T>)this.getHibernateTemplate().execute(new HibernateCallback(){

			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				// zqd 上午11:24:11
				Page p=new Page<T>();
				String classname=entityClass.getName();
				Query query=session.createQuery("select o from "+classname+" as o");
				if(pageNum!=-1&&maxResult!=-1){
					query.setFirstResult((pageNum-1)*maxResult);
					query.setMaxResults(maxResult);
				}
				p.setPageItems(query.list());
				p.setPageNo(pageNum);
				
				query=session.createQuery("select count(*) from "+classname);
				long sum=(Long)query.uniqueResult();
				if(sum%maxResult>0)
					p.setTotalPageNum((sum/maxResult)+1);
				else
					p.setTotalPageNum(sum/maxResult);
				return p;
			}
			
		});
	}
	
}
